// 此vm参数为页面的实例，可以通过它引用vuex中的变量
import { goLoginPage } from '@/common/utils/login'
import { API_BASE_URL, TOKEN_KEY } from '@/common/config'

export const Request = (vm) => {
  // 初始化请求配置
  uni.$uv.http.setConfig((config) => {
    config = {
      baseURL: API_BASE_URL,
      dataType: 'json',
      // #ifndef MP-ALIPAY
      responseType: 'text',
      // #endif
      // 注：如果局部custom与全局custom有同名属性，则后面的属性会覆盖前面的属性，相当于Object.assign(全局，局部)
      custom: {}, // 全局自定义参数默认值

      header: {
        Accept: 'application/json',
        // #ifdef H5 || ELECTRON
        appid: 'wx-web-appid',
        // #endif
        // #ifndef H5 || ELECTRON
        Referer: 'https://code0xff.com/wx-app-appid/app/page-frame.html',
        // #endif
      },

      // #ifdef H5 || APP || MP
      timeout: 600000,
      // #endif
      // #ifdef APP-PLUS
      sslVerify: true,
      // #endif
      // #ifdef H5
      // 跨域请求时是否携带凭证（cookies）仅H5支持（HBuilderX 2.6.15+）
      withCredentials: false,
      // #endif
      // #ifdef APP-PLUS
      firstIpv4: false, // DNS解析时优先使用ipv4 仅 App-Android 支持 (HBuilderX 2.8.0+)
      // #endif
    }

    return config
  })

  // 请求拦截
  uni.$uv.http.interceptors.request.use((config) => {
    if (!config.header.Authorization) {
      let token = uni.getStorageSync(TOKEN_KEY)
      config.header.Authorization = `Bearer ${token.token}`
    }

    return config
  }, config => { // 可使用async await 做异步操作
    return Promise.reject(config)
  })

  // 响应拦截
  uni.$uv.http.interceptors.response.use((response) => {
    if (response.statusCode === 429) {
      uni.$uv.toast('您的操作过于频繁，请稍后再试')
      return Promise.reject('您的操作过于频繁，请稍后再试')
    }

    const data = response.data
    const custom = response.config?.custom
    if (response.statusCode >= 400 && response.statusCode !== 401) {
      if (!custom?.catch) {
        uni.$uv.toast(data.message)
      }

      console.error(data)
      getApp().globalData.sentry.captureMessage(data.message, data)
      return Promise.reject(data)
    }

    // 通过上面优先处理错误的 statusCode, 401 未授权登录除外
    // 没有错误后，再处理 raw 的情况
    if (custom?.raw) {
      return response
    }

    // 401 未授权时跳转登录
    if (response.statusCode === 401) {
      uni.removeStorageSync(TOKEN_KEY)
      goLoginPage()
      return new Promise(() => {})
    }

    return data
  }, (response) => {
    // 对响应错误做点什么 （statusCode !== 200）
    return Promise.reject(response)
  })
}
